問題解説: Docker 実技1

問題文

このネットワークでServerからRouterにpingを実行した際に、172.16.0.254からは応答がありましたが、10.0.0.254からは応答がありませんでした。
原因を突きとめ、問題を解決してください。

ゴール

Serverから10.0.0.254にpingが通ること

トラブルの概要

  • Routerへのpingがdocker0の方にルーティングされてしまい、想定していない所にパケットが流れていってしまっている。

解説

Dockerは、dockerdが起動する際にdocker0というブリッジを作成します。このブリッジはコンテナがインターネットに接続する際に使われるブリッジになります。

今回、docker0のIPアドレスは10.0.0.1/16になっています。そのため、10.0.0.0/16宛のパケットはdocker0から送信されることになります。そのせいで、10.0.0.254からpingが返ってこないように見えていました。

解決するためには、10.0.0.0/16宛のパケットがVyOS側に届けば十分なので、docker0のブリッジを削除すれば十分なのですが、そうしてしまうとDockerが使えなくなってしまいます。docker0はローカルでのみ使われること(外部からそこに直接IPアドレスを指定してアクセスすること)は基本的にないので、docker0のサブネットを使われていないサブネットにすることで解決します。

docker0のサブネットを変更するためには、systemdのUnitファイルを編集してdockerdの起動時の引数を指定するか、/etc/docker/daemon.conf内で指定することで変更できます。ですが、一般的にはsystemdのデフォルトの引数は変更しない方が良いので、/etc/docker/daemon.jsonの設定を書き換えた方が良いでしょう。

解答例

ServerにSSHに、ping 10.0.0.254を実行してみても応答が返ってこないことが確認できた。

ip routeを実行してみると、10.0.0.254はデフォルトゲートウェイではなくdocker0にルーティングされていることが分かる。そのため、/etc/docker/daemon.jsonを以下のように書き換えた。

{
    "bip": "10.1.0.1/16"
}

その後、以下のコマンドでDockerを再起動した。すると、10.0.0.254からpingが返ってくる事が確認できた。

採点基準

10.0.0.254からpingが返ってくるようであれば250点与えていますが、本来出来ていたことができなくなっていた場合、若干の減点があります。

講評

この問題は作問者が実際にICTSC8の本戦で遭遇したトラブルを再現した問題でした。

いくつかのチームで、Dockerを停止させたりstatic routeを張ったりしてpingを通すチームが見られました。問題を解決するという意味では問題がないので点数を与えていますが、そのままではDockerの動作に影響を与える可能性があります。そのため、コンテナは動いていませんでしたが、多少の減点があると思います。

Routerに手を加えているチームも何チームか見られました。その解法の場合、そもそもpingが通らなかったり、インターネットへの疎通性が失われてしまっていました。問題文でRouterに問題がありそうな書き方をしましたが、問題が発生した際には、pingの送信元に近い方から検証していき、順番に障害を取り除いていくほうが簡単だと思います(tracerouteやtcpdumpなどを使えば、Serverに問題があることが分かると思います)。

ほとんど模範解答通りだったのですが、bipをグローバルIPアドレスにしている方もいました。こうしてしまうと、Routerにはpingが通るようになりますが、インターネットの一部空間へ疎通できなくなってしまいます。その空間が未割り当てなら点数の減点幅を抑えようかと考えましたが、Intelが確保していたので、手動でstatic route張ったときと同じ程度に減点しています。

https://www.iana.org/assignments/ipv4-address-space/ipv4-address-space.xhtml

余談ですが、ipコマンド使ってあげてください。アドレスの確認はもちろん、ルーティングテーブルの確認や仮想ネットワークデバイスの作成・削除も同じコマンドからできるのでいろいろと楽になると思います。

https://qiita.com/miyu/items/0cac69b6810dbbc56a9b